package grimbo.goodwinfooty.server.mvc;

import grimbo.goodwinfooty.server.ByteUtils;
import grimbo.goodwinfooty.server.FootyMatrixLoader;
import grimbo.goodwinfooty.server.fileupload.FileUploadHelper;
import grimbo.goodwinfooty.service.model.FootyMatrix;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;

/**
 * Uploads an xls file and prints it.
 */
public class ParseXLSController extends AbstractController {
	private static final String CNAME = UploadXLSController.class.getName();
	private static final Logger log = Logger.getLogger(CNAME);

	@Override
	protected ModelAndView handleRequestInternal(HttpServletRequest req,
			HttpServletResponse res) throws Exception {
		Map params = new FileUploadHelper().parseRequestMemory(req);
		String outputType = null;
		Object ob = params.get("outputType");
		if (ob instanceof List) {
			outputType = (String) ((List) ob).get(0);
		}
		byte[] xlsBytes = getXlsFileBytes(params);

		ModelAndView mandv = null;

		if ("csv".equals(outputType)) {
			List csv = null;
			try {
				csv = (List) createFootyMatrix(xlsBytes, outputType);
			} catch (FileUploadException e) {
				throw new IOException(e);
			}
			res.setContentType("text/plain");
			mandv = new ModelAndView("output-csv", "csv", csv);
		} else {
			FootyMatrix fm = null;
			try {
				fm = (FootyMatrix) createFootyMatrix(xlsBytes, outputType);
			} catch (FileUploadException e) {
				throw new IOException(e);
			}
			mandv = new ModelAndView("output-footy-matrix", "footyMatrix", fm);
		}

		return mandv;
	}

	private Object createFootyMatrix(byte[] xlsBytes, String outputType)
			throws FileUploadException, IOException {
		try {
			FootyMatrixLoader loader = new FootyMatrixLoader();
			if ("csv".equals(outputType)) {
				return loader.loadAsCSV(new ByteArrayInputStream(xlsBytes));
			} else {
				return loader.loadAsFootyMatrix(new ByteArrayInputStream(
						xlsBytes));
			}
		} catch (Exception e) {
			throw new IOException(e);
		}
	}

	private byte[] getXlsFileBytes(Map params) throws FileUploadException,
			IOException {
		final String MNAME = "getXlsFileBytes(HttpServletRequest)";
		final boolean DEBUG = log.isLoggable(Level.FINE);

		byte[] bytes = null;
		Object ob = params.get("xls-file");
		if (ob instanceof FileItem) {
			FileItem fi = (FileItem) ob;
			bytes = ByteUtils.readStream(fi.getInputStream());
		}
		return bytes;
	}

}
